package com.hzit.loan.pay.service.impl;

import com.hzit.loan.pay.commonApi.enums.PayStatusEnum;
import com.hzit.loan.pay.commonApi.req.PayReq;
import com.hzit.loan.pay.commonApi.resp.PayNotifyData;
import com.hzit.loan.pay.commonApi.resp.TaskTradeQueryRespData;
import com.hzit.loan.pay.commonApi.utils.IdWorker;
import com.hzit.loan.pay.mapper.PaySerialMapper;
import com.hzit.loan.pay.model.PaySerial;
import com.hzit.loan.pay.service.IPaySerialService;
import com.hzit.loan.pay.utils.RedisUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 支付流水相关接口
 */
@Service
public class PaySerialServiceImpl implements IPaySerialService {


    @Autowired
    private PaySerialMapper paySerialMapper;


    @Override
    public  PaySerial addPaySerial(PayReq payReq) {

        //记录当前线程， 锁的次数+1 -1

        //K K V

        //锁住当前对象  线程id+1
        synchronized (this){
            System.out.println("-----------");

            //锁住当前对象 线程id+1+1
            synchronized (this){
                System.out.println("==================");

            }
        }




        try {

            // 1.互斥,集群环境下，只有1个线程能够获取锁 利用redis setnx命令的原子性
            // 调用redis set nx   key test

            // 调用redis 过期时间。 expire  test5s +5S  key自动删除   lua脚本保证set nx 和expire 原子性

            //2.死锁 设置过期时间

            //3.性能 锁的粒度要小
//            RedisUtil.lock();
            //6s
            PaySerial paySerial = paySerialMapper.queryByMchOrderId(payReq.getMchOrderId());
            if (!ObjectUtils.isEmpty(paySerial)){
                return null;
            }

            PaySerial record = new PaySerial();
            record.setMchId(payReq.getMchId());
            record.setUserId(payReq.getUserId());
            IdWorker worker = new IdWorker(1,1,1);
            String paySerialNo = String.valueOf(worker.nextId());
            record.setMchOrderNo(payReq.getMchOrderId());
            record.setPayChannel(payReq.getPayChannel());
            record.setPayWay(payReq.getPayWay());
            record.setPaySerialNo(paySerialNo);
            record.setPayChannel(payReq.getPayChannel());
            record.setCreateTime(new Date());
            record.setUpdateTime(new Date());
            record.setMchOrderAmount(new BigDecimal(payReq.getOrderAmount()));
            record.setStatus(PayStatusEnum.UN_PAY.getCode().toString());
            paySerialMapper.insertSelective(record);

            return record;

        }finally {
            //调用 del方法
//            RedisUtil.unLcok();
        }       /************************检查订单是否存在未支付的未支付或者支付中的流水。如果存在就返回******************************/


        /************************检查订单是否存在未支付的未支付或者支付中的流水。如果存在就返回******************************/



    }

    @Override
    public PaySerial queryByPaySerialNoOrMchOrderNo(String paySerialNo, String mchOrderNo) {



        PaySerial paySerial =  paySerialMapper.queryByPaySerialNo(paySerialNo);

        paySerialMapper.queryByMchOrderId(mchOrderNo);

       return paySerial;
    }

    @Override
    public PaySerial updatePaySerialNo(PaySerial paySerial) {
        return null;
    }

    @Override
    public List<TaskTradeQueryRespData> queryByPayChannel(String payChannel) {


        // entify.model dao层
        // vo 业务层

        List<PaySerial> paySerialList = paySerialMapper.queeryByPayChannel(payChannel);

        if (CollectionUtils.isEmpty(paySerialList)){
            return null;
        }

        List<TaskTradeQueryRespData> dataList = new ArrayList<TaskTradeQueryRespData>();
        for (PaySerial p:paySerialList){
            TaskTradeQueryRespData queryRespData = new TaskTradeQueryRespData();

            BeanUtils.copyProperties(p,queryRespData);

            dataList.add(queryRespData);
        }

        return dataList;

    }

    @Override
    public String updatePaySerial(PayNotifyData payNotifyData) {

        PaySerial record = new PaySerial();

        record.setStatus(payNotifyData.getTradeStatus());
//        record.setBankRespNo(payNotifyData.get);
        record.setBankRespMsg(payNotifyData.getStatusDesc());
        record.setPaySuccessTime(payNotifyData.getFinishedTime());
        record.setUpdateTime(new Date());

        paySerialMapper.updateByPrimaryKeySelective(record);

        return "success";
    }

    public static void main(String[] args) {

    }


}
